package com.capgemini.cn.authority.bootstrap;

import com.capgemini.cn.authority.core.cache.RedisCachingAuthenticator;
import com.capgemini.cn.authority.core.enums.ParameterConstant;
import lombok.Getter;
import lombok.Setter;
import org.pac4j.core.client.Client;
import org.pac4j.core.client.DirectClient;
import org.pac4j.core.config.Config;
import org.pac4j.core.credentials.Credentials;
import org.pac4j.core.credentials.UsernamePasswordCredentials;
import org.pac4j.springframework.security.web.LogoutFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.util.ObjectUtils;

import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

/**
 * Created at 2017/9/8
 *
 * @author Andriy
 */
public class SecurityLogoutFilter extends LogoutFilter {

    private final Logger logger = LoggerFactory.getLogger(SecurityLogoutFilter.class);

    @Getter
    @Setter
    @Autowired
    @Qualifier(value = RedisCachingAuthenticator.COMPONENT_NAME)
    private RedisCachingAuthenticator redisCachingAuthenticator;

    public SecurityLogoutFilter() {
    }

    public SecurityLogoutFilter(Config config) {
        super(config);
    }

    public SecurityLogoutFilter(Config config, String defaultUrl) {
        super(config, defaultUrl);
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        super.init(filterConfig);
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
        final HttpServletRequest request = (HttpServletRequest) req;
        final HttpServletResponse response = (HttpServletResponse) resp;
        final String username = request.getAttribute(ParameterConstant.USER_NAME.value()).toString();
        final String authToken = request.getAttribute(ParameterConstant.AUTHORIZATION_TOKEN.value()).toString();

        if (!ObjectUtils.isEmpty(username) && !ObjectUtils.isEmpty(authToken)) {
            List<Client> clientList = this.getConfig().getClients().getClients();
            for (final Client currentClient : clientList) {
                if (currentClient instanceof DirectClient) {
                    logger.debug("Performing authentication for direct client: {}", currentClient);
                    final Credentials credentials = new UsernamePasswordCredentials(username, authToken, currentClient.getName());
                    logger.debug("credentials: {}", credentials);
                    if (!ObjectUtils.isEmpty(credentials)) {
                        this.redisCachingAuthenticator.removeFromCache(credentials);
                    }
                }
            }
        }
        super.doFilter(request, response, chain);
    }
}
